package com.wn.main.ui.mine

import android.view.LayoutInflater
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.ConvertUtils
import com.blankj.utilcode.util.ToastUtils
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
import com.wn.common.constant.USER_ACTIVITY_INFO
import com.wn.common.constant.USER_ACTIVITY_SETTING
import com.wn.common.model.ArticleList
import com.wn.common.provider.LoginServiceProvider
import com.wn.common.provider.UserServiceProvider
import com.wn.framework.base.BaseFragment
import com.wn.framework.decoration.NormalItemDecoration
import com.wn.framework.ext.onClick
import com.wn.main.R
import com.wn.main.databinding.FragmentMineBinding
import com.wn.main.databinding.FragmentMineHeaderBinding
import com.wn.main.ui.mine.viewmodel.MineViewModel
import com.wn.main.ui.system.adapter.SystemArticleAdapter
import com.wn.network.error.ERROR
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * @Author: wn
 * @Date: 2025/6/13 15:38
 * @Description: 个人中心模块 -- 资讯展示
 */
@AndroidEntryPoint
class MineFragment : BaseFragment<FragmentMineBinding>(), OnRefreshLoadMoreListener {

  override fun getLayoutRes() = R.layout.fragment_mine

  private val viewModel by viewModels<MineViewModel>()

  // 页码
  private var mPage = 1

  @Inject
  lateinit var mAdapter: SystemArticleAdapter

  @Inject
  lateinit var normalItemDecoration: NormalItemDecoration

  // 头布局
  private val mHeadBinding: FragmentMineHeaderBinding by lazy {
    FragmentMineHeaderBinding.inflate(LayoutInflater.from(requireContext()))
  }

  override fun initData() {
    mHeadBinding.apply {
      /**
       * LiveDate 是 粘性的 当登陆 或者注册后 liveData 有值 会触发该方法
       * 但是 刚来到此页面时 不会触发，所以通过 getUserInfo 渲染页面
       */
      user = UserServiceProvider.getUserInfo()
      UserServiceProvider.getUserLiveData().observe(this@MineFragment) {
        // 设置用户信息 -- 退出时 liveData 设置为 null
        user = it
      }
    }
  }

  override fun initView() {
    // 初始化 list
    initRecyclerView()
    // 初始化 头布局
    initHeadView()
    // 注册 点击监听 -- 跳转新页面
    initListener()
  }

  /**
   * 初始化 list
   */
  private fun initRecyclerView() {
    mBinding.apply {
      refreshLayout.apply {
        autoRefresh()
        setOnRefreshListener(this@MineFragment)
        setOnLoadMoreListener(this@MineFragment)
      }

      recyclerView.apply {
        layoutManager = LinearLayoutManager(requireContext())
        adapter = mAdapter
        addItemDecoration(normalItemDecoration.apply {
          setLastBottom(true)
          setFirstHeadMargin(true)
          setBounds(
            ConvertUtils.dp2px(12.0F),
            ConvertUtils.dp2px(12.0F),
            ConvertUtils.dp2px(12.0F),
            ConvertUtils.dp2px(12.0F)
          )
        })
      }
    }
    // 点击 是否收藏
    mAdapter.onClickCollect = { position, item ->
      /**
       * 登录后 收藏文章
       * 未登录 -- 跳转登录页
       */
      if (UserServiceProvider.isLogin()) {
        collectArticle(position, item)
      } else {
        LoginServiceProvider.toLogin(requireContext())
      }
    }
  }


  /**
   * 初始化 头布局
   */
  private fun initHeadView() {
    mAdapter.addHeadView(mHeadBinding.root)
  }

  /**
   * 注册 点击监听 -- 跳转新页面
   */
  private fun initListener() {
    // 针对 头部 布局
    mHeadBinding.apply {
      ivHead.onClick {
        /**
         * 登陆 了 去 用户信息 设置页
         * 没登陆  去 登陆页
         */
        if (UserServiceProvider.isLogin()) {
          ARouter.getInstance().build(USER_ACTIVITY_INFO).navigation()
        } else {
          LoginServiceProvider.toLogin(requireContext())
        }
      }

      ivSetting.onClick {
        ARouter.getInstance().build(USER_ACTIVITY_SETTING).navigation()
      }

      tvLikeTitle.onClick {
        ToastUtils.showShort("整体页面 结构 与 之前的 下拉刷新 上拉加载 几乎一致 ，这里 省略")
      }
    }
  }

  override fun onRefresh(refreshLayout: RefreshLayout) {
    mPage = 1
    getData()
  }

  override fun onLoadMore(refreshLayout: RefreshLayout) {
    mPage++
    getData()
  }

  /**
   * 获取推荐数据列表
   * 刷新 mPage = 1
   * 加载 mPage ++
   */
  private lateinit var job: Job
  private fun getData() {
    if (::job.isInitialized) job.cancel()
    job = lifecycleScope.launch {
      lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.getRecommendList(mPage).collect {
          if (mPage == 1) {
            // 加载更多 最后没有数据 得到的就是 null 所里 这里 骨架屏只针对首次刷新 即 mPage == 1
            mBinding.viewEmptyData.isVisible = it?.datas.isNullOrEmpty()
            // 这里 还有 header 的 显示 与 隐藏
            mHeadBinding.tvRecommendTitle.isVisible = it?.datas.isNullOrEmpty()

            it ?: return@collect
            mAdapter.setData(it.datas)
            mBinding.refreshLayout.finishRefresh()
          } else {
            mAdapter.addData(it?.datas)
            mBinding.refreshLayout.finishLoadMore()
          }
        }
      }
    }
  }

  private lateinit var jobCollect: Job

  /**
   * 收藏 or 取消收藏             -- adapter 更新某一个位置上的数据
   * @param position Int        -- 位置
   * @param item ArticleInfo    -- 数据
   */
  private fun collectArticle(position: Int, item: ArticleList.ArticleInfo) {
    if (::jobCollect.isInitialized) jobCollect.cancel()
    jobCollect = lifecycleScope.launch {
      lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
        // 收藏 or 取消收藏
        launch {
          val collect = item.collect ?: false
          viewModel.collectArticle(item.id ?: 0, collect) { code, _ ->
            // 错误码是 未登陆 跳转到登陆页
            if (code == ERROR.UN_LOGIN.code) {
              // 跳转到登陆页
              LoginServiceProvider.toLogin(requireContext())
            }
          }.collect {
            // 这里根据点击之前的 collect 状态来判断是收藏还是取消收藏  -- true 表示要取消 ,false 表示要收藏
            val tipsRes =
              if (collect) com.wn.framework.R.string.collect_cancel else com.wn.framework.R.string.collect_success
            ToastUtils.showShort(tipsRes)
            /**
             * 更改 item 的 collect 状态 取反
             * 更新某一个位置上的数据
             */
            item.collect = !collect
            mAdapter.updateItem(position, item)
          }
        }
        // 加载 loading
        launch {
          viewModel.loading.collect {
            if (it) showLoading() else dismissLoading()
          }
        }
      }
    }
  }

  /**
   * Home键或者锁屏 后 如果不 cancel 返回时数据会重复请求  -- stop
   * viewPager 滑动 -- pause
   */
  override fun onStop() {
    if (::job.isInitialized) job.cancel()
    if (::jobCollect.isInitialized) jobCollect.cancel()
    super.onStop()
  }
}